<template>
  <div>
    <a-upload
      v-model:file-list="fileList"
      :accept="accept"
      :list-type="listType"
      :multiple="max > 1"
      :max-count="max"
      :headers="headers"
      :custom-request="customRequest"
      :before-upload="beforeUpload"
      @change="change"
    >
      <a-button>
        <Icon type="icon-shangchuan" />
        上传
      </a-button>
    </a-upload>
    <div v-if="fileList.length > 0">
      <a @click="handleClearAll"><delete-outlined /> {{ t("common.clear") }}</a>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { ref, watch, nextTick, computed } from "vue";
import { DeleteOutlined } from "@ant-design/icons-vue";
import env from "/@/base/env";
import { Api, uploadReq } from "/@/api/common";
import { isAcceptFile, isOfficeFile, officeType, OFFICE_EXT } from "/@/utils/file";
import { getAuthHeaderInfo } from "/@/api/req";
import { message, Upload } from "ant-design-vue";
import type { UploadChangeParam, UploadProps, UploadFile } from "ant-design-vue";
import { UploadResult } from "/@/api/models";
import { useI18n } from "/@/locales/useI18n";
import { BizType, StorageType } from "/@/types/components";
import { UploadListType } from "ant-design-vue/es/upload/interface";
import { UploadRequestError } from "ant-design-vue/es/vc-upload/interface";
import { emit } from "process";
const props = withDefaults(
  defineProps<{
    value?: string | Array<string | undefined>;
    width?: number;
    listType?: UploadListType;
    //是否手动上传 默认自动上传，即选择图片后马上上传
    manual?: boolean;
    // 业务类型
    bizType?: string;
    // 存储类型
    storageType?: string;
    max?: number;
    uploadDesc?: string;
    unLoad?: boolean;
    accept?: string;
    maxSize?: number;
  }>(),
  {
    listType: "text",
    width: 150,
    max: 1,
    bizType: BizType.iot,
    storageType: StorageType.minio,
    unLoad: false,
    accept: OFFICE_EXT,
    maxSize: 200,
  }
);
const acceptArr = computed(() => {
  if (props.accept) {
    return props.accept.split(",");
  } else {
    return [];
  }
});
const emits = defineEmits<{
  (event: "change", url: string | Array<string | undefined>);
  (event: "beforeUpload");
  (event: "upload", e?: any);
}>();

const { t } = useI18n();
const handleClearAll = () => {
  fileList.value = [];
  emits("change", props.max && props.max > 1 ? [] : "");
};
const customRequest: UploadProps["customRequest"] = async (options) => {
  console.info("files", options.file);
  let formData = new FormData();
  formData.append("file", options.file);
  formData.append("bizType", props.bizType);
  formData.append("storageType", props.storageType);
  let url = env.baseUrl + Api.upload;

  if (props.unLoad) {
    // let req = await uploadReq(url, formData);
    setTimeout(() => {
      options.onSuccess && options.onSuccess({ status: "done", fileId: "123", url: "123" });
      emits("upload", options.file);
    }, 100);
  } else {
    loading.value = true;
    let req = await uploadReq(url, formData);
    loading.value = false;
    if (req) {
      options.onSuccess &&
        options.onSuccess({
          uid: req.fileId,
          fileId: req.fileId,
          name: req.originalFileName,
          url: req.url,
          status: "done",
          type: req.contentType,
        });
      console.info("options==>", options);
      emits("upload", options.file);
      // req?.fileId && message.success(t("common.operSuccess"));
    } else {
      let obj: UploadRequestError = {
        status: 500,
        name: "",
        message: "上传失败",
      };
      fileList.value.splice(fileList.value.length - 1, 1);
      options.onError && options.onError(obj);
    }
  }
};
const fileList = ref<Array<UploadFile<UploadResult>>>([]);
watch(
  () => props.value,
  () => {
    // 如value是undefined或者空数组 则清空
    if (!props.value || (props.value && Array.isArray(props.value) && props.value.length === 0)) {
      // handleClearAll();
      fileList.value = [];
    } else if (props.value && Array.isArray(props.value) && props.value.length > 0) {
      fileList.value = props.value.map((item, index) => {
        return {
          uid: index + "img",
          name: "imgs" + index,
          url: item,
          status: "done",
          type: "image/jpeg",
        };
      });
    } else if (props.value && !Array.isArray(props.value)) {
      // fileList.value = [{ uid: "img1", name: "img", url: props.value }];
    }
  },
  {
    immediate: true,
  }
);
const loading = ref(false);
const headers = getAuthHeaderInfo(true);
const beforeUpload: UploadProps["beforeUpload"] = (file) => {
  if (props.manual) {
    console.warn("手动上传功能开发中...", file);
    return false;
  }
  if (!isAcceptFile(file.name, acceptArr.value)) {
    message.warning(`支持上传${props.accept}文件格式`);
    console.info(fileList.value);
  }
  const isLt2M = file.size / 1024 / 1024 < props.maxSize;
  if (!isLt2M) {
    message.warning(`上传文件大小不能超过${props.maxSize}M`);
  }
  emits("beforeUpload");
  return (isAcceptFile(file.name, acceptArr.value) && isLt2M) || Upload.LIST_IGNORE;
};
const change = (info: UploadChangeParam<UploadFile<UploadResult>>) => {
  if (info.file.status === "uploading") {
    loading.value = true;
    return;
  } else if (info.file.status === "done") {
    loading.value = false;
    emits("upload");
    const res = info.file.response;
    if (res && res.fileId) {
      let value: string | Array<string | undefined> = "";
      if (props.max > 1) {
        value =
          fileList.value.map((item) => {
            return item.url || (item.response && item.response.url);
          }) || [];
      } else {
        value = res.url;
      }
      let doneLength = fileList.value.filter((item) => {
        return item.status === "done";
      }).length;
      // 文件状态全部为done再emit
      fileList.value.length === doneLength && emits("change", value);
    } else {
      message.error(t("common.uploadErr"));
    }
  } else if (info.file.status === "error") {
    loading.value = false;
    emits("upload");
    message.error(t("common.uploadErr"));
  } else if (info.file.status && info.file.status === "removed") {
    if (props.max > 1) {
      let imgArr =
        fileList.value.map((item) => {
          return item.url || (item.response && item.response.url);
        }) || [];
      emits("change", imgArr);
    } else {
      emits("change", "");
    }
  }
};
</script>
<style lang="less"></style>
